package com.tsfyun.scm.service.impl.system;

import cn.hutool.core.collection.CollectionUtil;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.util.TsfPreconditions;
import com.tsfyun.scm.dto.system.MailConfigDTO;
import com.tsfyun.scm.dto.system.TestMailConfigDTO;
import com.tsfyun.scm.entity.system.MailConfig;
import com.tsfyun.scm.mapper.system.MailConfigMapper;
import com.tsfyun.scm.service.system.IMailConfigService;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.util.MailUtil;
import com.tsfyun.scm.util.TsfWeekendSqls;
import com.tsfyun.scm.vo.system.MailConfigVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Objects;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>
 *  邮件配置服务实现类
 * </p>
 *

 * @since 2020-03-19
 */
@RefreshScope
@Service
public class MailConfigServiceImpl extends ServiceImpl<MailConfig> implements IMailConfigService {

    @Autowired
    private MailConfigMapper mailConfigMapper;

    @Value("${mail.retryTimes:2}")
    private int mailRetryTime;

    @Override
    public List<MailConfig> openList() {
        MailConfig mailConfig = new MailConfig();
        mailConfig.setDisabled(Boolean.FALSE);
        return super.list(mailConfig);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(MailConfigDTO dto) {
        MailConfig condition = new MailConfig();
        condition.setDisabled(Boolean.FALSE);
        List<MailConfig> activeList = super.list(condition);

        MailConfig mailConfig = beanMapper.map(dto,MailConfig.class);
        mailConfig.setDisabled(Boolean.FALSE);
        mailConfig.setRetryTimes(mailRetryTime);
        if(CollectionUtil.isNotEmpty(activeList)) {
            if (Objects.equals(dto.getIsDefault(), Boolean.TRUE)) {
                //取消以前设置的默认
                handleOldDefault();
            }
            mailConfig.setIsDefault(dto.getIsDefault());
        } else {
            //如果没有配置邮箱地址信息，则新增的记录修改为默认
            mailConfig.setIsDefault(Boolean.TRUE);
        }
        super.saveNonNull(mailConfig);
        removeMailMap();
    }

    private void removeMailMap() {
        ConcurrentHashMap<String, Properties> mailMap = MailUtil.getInstance().mailMap;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(MailConfigDTO dto) {
        MailConfig mailConfig = super.getById(dto.getId());
        TsfPreconditions.checkArgument(Objects.nonNull(mailConfig),new ServiceException("邮箱配置信息不存在"));
        mailConfig.setMailHost(dto.getMailHost());
        mailConfig.setMailUser(dto.getMailUser());
        mailConfig.setMailPassword(dto.getMailPassword());
        mailConfig.setMailPort(dto.getMailPort());
        mailConfig.setRetryTimes(mailRetryTime);
        if(Objects.equals(mailConfig.getDisabled(),Boolean.TRUE) && Objects.equals(dto.getIsDefault(),Boolean.TRUE)) {
            throw new ServiceException("该邮箱配置已被禁用，您不能将此设置为默认邮箱配置");
        }
        //如果由非默认变为默认则需要处理之前设置的默认的，如果是否默认未变更则无需处理
        if (!mailConfig.getIsDefault() && dto.getIsDefault()) {
            handleOldDefault();
        }
        mailConfig.setIsDefault(dto.getIsDefault());
        super.updateById(mailConfig);
        removeMailMap();
    }

    public void handleOldDefault( ) {
        MailConfig update = new MailConfig();
        update.setIsDefault(Boolean.FALSE);
        mailConfigMapper.updateByExampleSelective(update, Example.builder(MailConfig.class).where(TsfWeekendSqls.<MailConfig>custom()
                .andEqualTo(false,MailConfig::getIsDefault,Boolean.TRUE)).build());
        removeMailMap();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(Long id) {
        MailConfig mailConfig = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(mailConfig),new ServiceException("邮箱配置信息不存在"));
        super.removeById(id);
        removeMailMap();
    }

    @Override
    public List<MailConfigVO> allList() {
        return beanMapper.mapAsList(super.list(),MailConfigVO.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateDisabled(Long id, Boolean disabled) {
        MailConfig mailConfig = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(mailConfig),new ServiceException("邮箱配置信息不存在"));
        MailConfig update = new MailConfig();
        update.setDisabled(disabled);
        mailConfigMapper.updateByExampleSelective(update, Example.builder(MailConfig.class).where(
                TsfWeekendSqls.<MailConfig>custom().andEqualTo(false,MailConfig::getId, id)).build()
        );
        removeMailMap();
    }

    @Override
    public MailConfigVO detail(Long id) {
        MailConfig mailConfig = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(mailConfig),new ServiceException("邮箱配置信息不存在"));
        return beanMapper.map(mailConfig,MailConfigVO.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void setDefault(Long id, Boolean isDefault) {
        MailConfig mailConfig = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(mailConfig),new ServiceException("邮箱配置信息不存在"));

        if(Objects.equals(mailConfig.getDisabled(),Boolean.TRUE) && Objects.equals(isDefault,Boolean.TRUE)) {
            throw new ServiceException("该邮箱配置已被禁用，您不能将此设置为默认邮箱配置");
        }

        Boolean currentDefault = mailConfig.getIsDefault();
        if(!Objects.equals(mailConfig.getIsDefault(),isDefault)) {
            if(!Objects.equals(Boolean.TRUE,currentDefault) && isDefault) {
                //以前是非默认，现在置为默认，则需要取消以前的默认如果存在的话
                handleOldDefault( );
            }
            mailConfig.setIsDefault(isDefault);
        }
        super.updateById(mailConfig);
        removeMailMap();
    }

    @Override
    public Boolean checkConnect(TestMailConfigDTO dto) {
        return MailUtil.getInstance().checkSend(dto.getMailHost(),dto.getMailUser(),dto.getMailPassword(),dto.getMailPort());
    }
}
